import { VideoRepository, VideoSelect, VideoTypeWithChildren } from '@/lib/database/repositories';
import type { Video, VideoType } from '@prisma/client';
import { isVip } from '@/lib/auth/auth-utils';
import { cache } from 'react';

export type { Video, VideoType };

export interface VideoWithType extends Video {
  type: VideoType;
  noAccess?: boolean;
}

// 导出VideoTypeWithChildren类型，使其在组件中可用
export type { VideoTypeWithChildren };

export class VideoService {
  /**
   * 检查分类是否对指定VIP状态可见
   * @param type 分类对象
   * @returns 是否可见
   */
  private static isTypeAccessible = cache(async (type: VideoType): Promise<boolean> => {
    // 如果分类不可见，直接返回false
    if (!type.isVisible) {
      return false;
    }
    
    // 如果是VIP专属分类，但用户不是VIP
    if (type.isVip && !(await isVip())) {
      return false;
    }
    
    return true;
  });

  /**
   * 获取所有分类
   */
  static getAllTypes = cache(async (): Promise<VideoType[]> => {
    // Repository层会自动获取VIP状态
    return await VideoRepository.getAllVisibleTypes();
  });

  /**
   * 获取单个分类
   */
  static getTypeById = cache(async (typeId: number): Promise<VideoTypeWithChildren | null> => {
    // 使用getTypeWithChildren方法获取单个分类信息，包含子分类
    const type = await VideoRepository.getTypeWithChildren(typeId);
    if (!type) return null;
    
    // 仓库层已经处理了可见性和权限，这里无需再次检查
    return type;
  });

  /**
   * 获取首页轮播图数据
   */
  static getCarouselVideos = cache(async (limit = 5): Promise<VideoSelect[]> => {
    return await VideoRepository.getCarouselVideos(limit);
  });

  /**
   * 获取最新视频
   */
  static getNewestVideos = cache(async (limit = 12): Promise<VideoSelect[]> => {
    return await VideoRepository.getNewestVideos(limit);
  });

  /**
   * 获取最新视频(分页版)
   */
  static getNewestVideosPaged = cache(async (page = 1, pageSize = 24): Promise<{ videos: VideoSelect[]; total: number }> => {
    return await VideoRepository.getNewestVideosPaged(page, pageSize);
  });

  /**
   * 获取热门视频
   */
  static getHotVideos = cache(async (limit = 12): Promise<VideoSelect[]> => {
    return await VideoRepository.getHotVideos(limit);
  });

  /**
   * 获取高分视频
   */
  static getTopRatedVideos = cache(async (limit = 12): Promise<VideoSelect[]> => {
    return await VideoRepository.getTopRatedVideos(limit);
  });

  /**
   * 按分类获取视频
   */
  static getVideosByType = cache(async (
    typeId: number, 
    page = 1, 
    pageSize = 24,
    filters: {
      years?: string[];
      areas?: string[];
      types?: number[];
      sort?: 'newest' | 'hot' | 'rating';
      yearLessThan?: string;
      yearGreaterThan?: string;
    } = {}
  ): Promise<{ videos: VideoSelect[]; total: number }> => {
    // 当typeId为0时，查询所有视频
    if (typeId === 0) {
      return await VideoRepository.getVideosByTypeIds([], page, pageSize, {
        years: filters.years,
        areas: filters.areas,
        sort: filters.sort,
        yearLessThan: filters.yearLessThan,
        yearGreaterThan: filters.yearGreaterThan
      });
    }

    // 获取当前分类（已包含可见性过滤）
    const type = await VideoRepository.getTypeWithChildren(typeId);

    if (!type) {
      return { videos: [], total: 0 };
    }

    // 检查当前分类是否可见和用户是否有权限访问
    if (!(await VideoService.isTypeAccessible(type))) {
      return { videos: [], total: 0 };
    }
    
    // 确定要查询的分类ID
    let typeIds: number[] = [];
    
    // 先检查是否有指定的子分类筛选参数
    if (filters.types && filters.types.length > 0) {
      // 确保所有类型都是当前类型的子类型或当前类型本身
      const filteredTypes = filters.types.filter(id => 
        id === typeId || type.children.some(child => child.id === id)
      );
      
      // 如果有匹配的类型，则只使用这些类型ID进行筛选
      if (filteredTypes.length > 0) {
        console.log('[VideoService] 使用指定的子分类筛选:', filteredTypes);
        typeIds = filteredTypes;
      } else {
        // 如果没有匹配的类型，回退到默认逻辑
        console.log('[VideoService] 指定的子分类无效，使用默认类型:', typeId);
        typeIds = [typeId];
      }
    } else {
      // 没有子分类筛选参数，则使用顶级分类和所有子分类
      typeIds = [typeId];
      
      // 如果是父分类，获取所有子分类ID
      if (type.children.length > 0) {
        const childrenIds = type.children.map(child => child.id);
        typeIds = [...typeIds, ...childrenIds];
        console.log('[VideoService] 使用顶级分类及其所有子分类:', typeIds);
      }
    }

    // 查询视频
    return await VideoRepository.getVideosByTypeIds(typeIds, page, pageSize, {
      years: filters.years,
      areas: filters.areas,
      sort: filters.sort,
      yearLessThan: filters.yearLessThan,
      yearGreaterThan: filters.yearGreaterThan
    });
  });

  /**
   * 获取视频详情
   */
  static getVideoDetail = cache(async (id: number): Promise<VideoWithType | null> => {
    const video = await VideoRepository.getVideoWithType(id);

    // 如果视频不存在，直接返回null
    if (!video) return null;

    // 检查该视频是否可见
    if (!video.isVisible) {
      return null;
    }
    
    // 检查用户是否有VIP权限访问该视频
    const is_vip = await isVip();
    if (video.isVip && !is_vip) {
      // 表示视频存在但无权访问，通过状态码识别
      return { ...video, noAccess: true } as unknown as VideoWithType;
    }

    // 增加视频点击量 - 使用非阻塞方式执行，不影响页面加载
    // 使用void操作符确保不等待执行完成
    void VideoService.increaseHits(id);

    return video as VideoWithType;
  });

  /**
   * 增加视频点击量
   */
  static increaseHits = cache(async (id: number): Promise<void> => {
    await VideoRepository.increaseHits(id);
  });

  /**
   * 搜索视频
   */
  static searchVideos = cache(async (keyword: string, page = 1, pageSize = 24): Promise<{ videos: VideoSelect[]; total: number }> => {
    return await VideoRepository.searchVideos(keyword, page, pageSize);
  });

  /**
   * 获取相关视频推荐
   */
  static getRelatedVideos = cache(async (typeId: number, currentId: number, limit = 12): Promise<VideoSelect[]> => {
    return await VideoRepository.getRelatedVideos(typeId, currentId, limit);
  });

  /**
   * 获取视频年份列表（用于筛选）
   */
  static getYearsList = cache(async (): Promise<string[]> => {
    return await VideoRepository.getYearsList();
  });

  /**
   * 获取视频地区列表（用于筛选）
   */
  static getAreasList = cache(async (): Promise<string[]> => {
    return await VideoRepository.getAreasList();
  });

  /**
   * 获取最近24小时内的视频
   */
  static getLast24HoursVideos = cache(async (page = 1, pageSize = 24): Promise<{ videos: VideoSelect[]; total: number }> => {
    return await VideoRepository.getLast24HoursVideos(page, pageSize);
  });
} 